package gameLogic

import (
	"fmt"
	"net"

	"github.com/sirupsen/logrus"
	lua "github.com/yuin/gopher-lua"
)

// tcp服务器实现
type TcpSvr struct {
	listener net.Listener
}

func (s *TcpSvr) Listen(port int) {
	s.listener, _ = net.Listen("tcp", fmt.Sprintf("0.0.0.0:%d", port))
	logrus.Infoln("start listen tcp in :", port)
}
func (s *TcpSvr) Accept() {
	for {
		conn, err := s.listener.Accept()
		if err != nil {
			logrus.Println("tcp accept error:", err.Error())
			continue
		}
		logrus.Println(conn.RemoteAddr().String(), " tcp connected!")
		go s.handle(conn)
	}
}
func (s *TcpSvr) handle(conn net.Conn) {
	var clientInfoNoLockMap map[string]string //用于保存客户端的信息，每个函数都要带下去，不存在并发，无需加锁
	clientInfoNoLockMap = make(map[string]string)
	luaVm := lua.NewState() //lua虚拟机
	defer luaVm.Close()     //TODO 目前是一个连接就新建一个lua虚拟机，后续需要login成功以后再去新建
	//处理连接，进入游戏逻辑
	for {
		//读
		buffer := make([]byte, 4096)
		read_size, err := conn.Read(buffer)
		if err != nil {
			logrus.Errorln("read from :", conn.RemoteAddr().String(), " error:", err.Error())
			conn.Close()
			return
		}
		//解包处理
		res_buffer := GameLogicEntry(&clientInfoNoLockMap, buffer[0:read_size], luaVm)
		res_buffer = append(res_buffer, '\n')
		//回包
		n, err := conn.Write(res_buffer) //回包给客户端
		if err != nil {
			logrus.Error("write to ", conn.RemoteAddr().String(), " failed! err:", err.Error())
			conn.Close()
			return
		}
		logrus.Infoln("write to ", conn.RemoteAddr().String(), " success in ", n, " byte")
	}
}
